package io.unicorn.modules.watersub.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.unicorn.common.utils.PageUtils;
import io.unicorn.common.utils.Query;
import io.unicorn.modules.sys.dao.SysDictDao;
import io.unicorn.modules.sys.entity.SysDictEntity;
import io.unicorn.modules.water.dao.TAccountManageDao;
import io.unicorn.modules.water.dao.TClientInfoDao;
import io.unicorn.modules.water.dao.TDeviceInfoDao;
import io.unicorn.modules.water.dao.TDevicesTypeDao;
import io.unicorn.modules.water.entity.TAccountManageEntity;
import io.unicorn.modules.water.entity.TClientInfoEntity;
import io.unicorn.modules.water.entity.TDeviceInfoEntity;
import io.unicorn.modules.water.entity.TDevicesTypeEntity;
import io.unicorn.modules.watersub.service.TClientInfosubService;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;


@Service("tClientInfoSubService")
public class TClientInfosubServiceImpl extends ServiceImpl<TClientInfoDao, TClientInfoEntity> implements TClientInfosubService {
    @Autowired
    TDevicesTypeDao tDevicesTypeDao;

    @Autowired
    private TDeviceInfoDao tDeviceInfoDao;
    @Autowired
    private SysDictDao sysDictDao;

    @Autowired
    private TAccountManageDao tAccountManageDao;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        String ckey   = (String)params.get("ckey");

        String deptId = (String)params.get("dept");

        String key   = (String)params.get("key");
        String value = (String)params.get("value");

        IPage<TClientInfoEntity> page = this.page(
                new Query<TClientInfoEntity>().getPage(params),
                new QueryWrapper<TClientInfoEntity>()
                        .like(StringUtils.isNotBlank(ckey), "memo1", ckey)
                        .like(StringUtils.isNotBlank(value) && StringUtils.isNotBlank(key), key, value)
                        .eq("memo1", deptId)
                        .exists("select device_id from Gather_DB.dbo.t_device_info a,Gather_DB.dbo.t_devices_type b where Gather_DB.dbo.T_Client_Info.device_id = a.device_id and  a.type_id = b.type_id and b.type_code = 0 ")

        );

        Set<String> deviceIds = page.getRecords().stream().map(TClientInfoEntity::getDeviceId).collect(Collectors.toSet());
        if (deviceIds.size() > 0) {
            //如果集合中数据过多，需要拆分，sql server 不许超过2100，拆分依据1500
            //2022.6.2
            int dataSize = 2000;
            if (deviceIds.size() <= dataSize) dataSize = deviceIds.size();

            ArrayList newSet = new ArrayList(deviceIds);
            List<TDeviceInfoEntity> deviceList = new ArrayList<>();
            int st = 0;
            int size = deviceIds.size();

            do {
                Set setSet = new TreeSet(newSet.subList(st, st + dataSize > deviceIds.size() ? st + size : st + dataSize));
                deviceList.addAll(tDeviceInfoDao.selectList(Wrappers.lambdaQuery(TDeviceInfoEntity.class).in(TDeviceInfoEntity::getDeviceId, setSet)));
                st += dataSize;
                size -= dataSize;
            } while (size > 0);

            Map<String, TDeviceInfoEntity> deviceMap = deviceList.stream().collect(Collectors.toMap(TDeviceInfoEntity::getDeviceId, Function.identity()));
            //查询类型
            Set<Integer> typeIds = deviceList.stream().map(TDeviceInfoEntity::getTypeId).collect(Collectors.toSet());
            List<TDevicesTypeEntity> typeList = tDevicesTypeDao.selectList(Wrappers.lambdaQuery(TDevicesTypeEntity.class).in(TDevicesTypeEntity::getTypeId, typeIds));
            Map<Integer, String> hashMap = typeList.stream().collect(Collectors.toMap(TDevicesTypeEntity::getTypeId, TDevicesTypeEntity::getTypeName));

            page.getRecords().forEach(e -> {
                e.setClientDeviceInfo(deviceMap.get(e.getDeviceId()));
                e.setDesc11(e.getClientDeviceInfo().getMasterNum().toString());
                e.setDesc12(e.getClientDeviceInfo().getSlaveNum().toString());
                e.setDesc13(e.getClientDeviceInfo().getCardNum().toString());
                e.setDesc14(e.getClientDeviceInfo().getRouteNum().toString());
                e.setDesc15(e.getClientDeviceInfo().getMeterNum().toString());
                e.setDesc4(hashMap.get(e.getClientDeviceInfo().getTypeId()));
            });

            //setSet.add(new TreeSet(newSet.subList(st, deviceIds.size())));
        }

        return new PageUtils(page);
    }

    @Override
    public byte[] genExcelTemplate(Map<String, Object> params) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ExcelWriter excelWriter = EasyExcel.write(os).build();
        //dept 如果是空就导出空表，否则就到处对应小区信息
        String deptId = (String)params.get("dept");
        if (!StringUtils.isNotBlank(deptId)) deptId = "ProNameIsEmpty";

        List<TClientInfoEntity> listData = baseMapper.selectList(new QueryWrapper<TClientInfoEntity>().eq("memo1", deptId).orderByAsc("device_id"));
        //读取关联的设备信息
        Set<String> deviceIds = listData.stream().map(TClientInfoEntity::getDeviceId).collect(Collectors.toSet());
        /*
        if (deviceIds.size() > 0) {
            List<TDeviceInfoEntity> deviceList = tDeviceInfoDao.selectList(Wrappers.lambdaQuery(TDeviceInfoEntity.class).in(TDeviceInfoEntity::getDeviceId, deviceIds));
            Map<String, TDeviceInfoEntity> deviceMap = deviceList.stream().collect(Collectors.toMap(TDeviceInfoEntity::getDeviceId, Function.identity()));
            //查询类型
            Set <Integer> typeIds = deviceList.stream().map(TDeviceInfoEntity::getTypeId).collect(Collectors.toSet());
            List<TDevicesTypeEntity> typeList = tDevicesTypeDao.selectList(Wrappers.lambdaQuery(TDevicesTypeEntity.class).in(TDevicesTypeEntity::getTypeId, typeIds));
            Map<Integer, String> hashMap = typeList.stream().collect(Collectors.toMap(TDevicesTypeEntity::getTypeId, TDevicesTypeEntity::getTypeName));
            listData.forEach(e -> {
                        e.setClientDeviceInfo(deviceMap.get(e.getDeviceId()));
                        e.setDesc11(e.getClientDeviceInfo().getMasterNum().toString());
                        e.setDesc12(e.getClientDeviceInfo().getSlaveNum().toString());
                        e.setDesc13(e.getClientDeviceInfo().getCardNum().toString());
                        e.setDesc14(e.getClientDeviceInfo().getRouteNum().toString());
                        e.setDesc15(e.getClientDeviceInfo().getMeterNum().toString());
                        e.setDesc4(hashMap.get(e.getClientDeviceInfo().getTypeId()));
                    }
            );
        }
        */

        if (deviceIds.size() > 0) {
            //如果集合中数据过多，需要拆分，sql server 不许超过2100，拆分依据1500
            //2022.6.2
            int dataSize = 2000;
            if (deviceIds.size() <= dataSize) dataSize = deviceIds.size();

            ArrayList newSet = new ArrayList(deviceIds);
            List<TDeviceInfoEntity> deviceList = new ArrayList<>();
            int st = 0;
            int size = deviceIds.size();

            do {
                Set setSet = new TreeSet(newSet.subList(st, st + dataSize > deviceIds.size() ? st + size : st + dataSize));
                deviceList.addAll(tDeviceInfoDao.selectList(Wrappers.lambdaQuery(TDeviceInfoEntity.class).in(TDeviceInfoEntity::getDeviceId, setSet)));
                st += dataSize;
                size -= dataSize;
            } while (size > 0);

            Map<String, TDeviceInfoEntity> deviceMap = deviceList.stream().collect(Collectors.toMap(TDeviceInfoEntity::getDeviceId, Function.identity()));
            //查询类型
            Set<Integer> typeIds = deviceList.stream().map(TDeviceInfoEntity::getTypeId).collect(Collectors.toSet());
            List<TDevicesTypeEntity> typeList = tDevicesTypeDao.selectList(Wrappers.lambdaQuery(TDevicesTypeEntity.class).in(TDevicesTypeEntity::getTypeId, typeIds));
            Map<Integer, String> hashMap = typeList.stream().collect(Collectors.toMap(TDevicesTypeEntity::getTypeId, TDevicesTypeEntity::getTypeName));

            listData.forEach(e -> {
                e.setClientDeviceInfo(deviceMap.get(e.getDeviceId()));
                e.setDesc11(e.getClientDeviceInfo().getMasterNum().toString());
                e.setDesc12(e.getClientDeviceInfo().getSlaveNum().toString());
                e.setDesc13(e.getClientDeviceInfo().getCardNum().toString());
                e.setDesc14(e.getClientDeviceInfo().getRouteNum().toString());
                e.setDesc15(e.getClientDeviceInfo().getMeterNum().toString());
                e.setDesc4(hashMap.get(e.getClientDeviceInfo().getTypeId()));
            });

            //setSet.add(new TreeSet(newSet.subList(st, deviceIds.size())));
        }

        WriteSheet writeSheet = EasyExcel.writerSheet(0, "Sheet1")
                .includeColumnFiledNames(
                        new HashSet<>(Arrays.asList(
                        new String[]{"deviceId","memo1","buildNum","unitNum","houseNum",
                                "proName","clientId","clientName",
                                "desc11","desc12","desc13","desc14","desc15",
                                "clientIdCard","meterCode","stampCode","calibre",
                                "desc1","desc2","desc4","desc5","desc3","desc6","desc7","desc8","desc9","desc10","desc16","memo2"})))
                .head(TClientInfoEntity.class).build();
        excelWriter.write(listData, writeSheet);

        //字典信息
        //小区字典
        writeSheet = EasyExcel.writerSheet(2, "小区名称字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"proName"})))
                .head(TAccountManageEntity.class).build();
        excelWriter.write(tAccountManageDao.selectList(new QueryWrapper<TAccountManageEntity>()),writeSheet);

        writeSheet = EasyExcel.writerSheet(3, "水表类型字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_device_type")),writeSheet);

        writeSheet = EasyExcel.writerSheet(4, "水表口径字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_calibre")),writeSheet);

        writeSheet = EasyExcel.writerSheet(5, "使用性质字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_use_type")),writeSheet);

        writeSheet = EasyExcel.writerSheet(6, "安装位置字典")
                .includeColumnFiledNames(new HashSet<>(Arrays.asList(new String[]{"code"})))
                .head(SysDictEntity.class).build();
        excelWriter.write(sysDictDao.selectList(new QueryWrapper<SysDictEntity>().eq("name", "dict_fix_addr")),writeSheet);

        excelWriter.finish();

        return os.toByteArray();
    }


}
